﻿
using Castle.Core.Internal;
using Coldairarrow.Business.Interface;
using Coldairarrow.Entity.Base_Manage;
using Coldairarrow.Entity.Interface;
using Coldairarrow.Util;
using Microsoft.Extensions.Options;
using NetTopologySuite.Index.HPRtree;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlTypes;
using System.Diagnostics.Tracing;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Net;
using System.Reflection.Metadata;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;
using static org.apache.zookeeper.ZooDefs;

namespace Coldairarrow.Business.Interface
{
    public class RE_ProductInventoryInterfaceBusiness : REInterface_BaseBusiness, IJob_Business, ITransientDependency
    {
        //接口信息
        public Base_InterfaceOption RE_Query;


        public RE_ProductInventoryInterfaceBusiness()
        {
            this.InterfaceName = "RE库存库龄";
            //索引字段
            this.MapFields = GetMapField("RE_Query");
            //索引字段
            //Keys = GetKeys("addRow");

            //获取此接口的所有API信息
            this.interfaceOption = SqlDb.GetListBySql<Base_InterfaceOption>(@$"SELECT * FROM  Base_InterfaceOption(NOLOCK) WHERE Name='{InterfaceName}' ");
            RE_Query = this.interfaceOption.Where(x => x.OperateType == "RE_Query").First();

            //查询执行前的事件
            this.BeforeQueryEvent += InterfaceBusiness_BeforeQueryEvent;
            //查询执行中的事件
            this.OnQueryEvent += InterfaceBusiness_OnQueryEvent;
            //查询执行中的事件
            this.AfterQueryEvent += InterfaceBusiness_AfterQueryEvent;

            //执行非查询请求中的事件
            this.OnNoQueryEvent += InterfaceBusiness_OnNoQueryEvent;

        }

        /// <summary>
        /// 执行非查询请求中事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="RE_NoQueryEventArgs"></param>
        private void InterfaceBusiness_OnNoQueryEvent(object sender, RE_NoQueryEventArgs RE_NoQueryEventArgs)
        {
        }

        /// <summary>
        /// 查询执行前的事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="queryEventArgs"></param>
        private async void InterfaceBusiness_BeforeQueryEvent(object sender, RE_QueryEventArgs queryEventArgs)
        {
            try
            {
                //获取appId
                RE_BaseReqDTO RE_BaseReq = new RE_BaseReqDTO();
                queryEventArgs.CustomData = RE_BaseReq;
                //获取配置参数
                this.SqlDb._conStrings[0] = JsonSettingHelper.GetSetting("Database:BaseDb:ConnectionString");
                var parameters = this.SqlDb.GetListBySql<Base_ConfigParameter>(@$"SELECT * FROM  Base_ConfigParameter(NOLOCK) WHERE Code='RE'");
                RE_BaseReq.AppKey = parameters.Where(x => x.Name == "appKey").First().Value;
                RE_BaseReq.AppToken = parameters.Where(x => x.Name == "appToken").First().Value;
                RE_BaseReq.SoapEnv = parameters.Where(x => x.Name == "SoapEnv").First().Value;
                RE_BaseReq.Ns1 = parameters.Where(x => x.Name == "Ns1").First().Value;
                RE_BaseReq.Service = RE_Query.InterfaceType;
                //设置单次查询的页面数量
                queryEventArgs.Page.PageSize = queryEventArgs.APINodes.Where(x => x.TargetField == "pageSize").First().SourceField.ToInt();
                //设置需要查询多久之前的数据
                //queryEventArgs.Page.Total = queryEventArgs.APINodes.Where(x => x.TargetField == "create_date_from").First().Notes.ToInt();
                queryEventArgs.Page.PageIndex = 1;
            }
            catch (Exception ex)
            {
                AddLog(SqlDb, ex.Message, InterfaceName, "erro", "");
            }
        }

        /// <summary>
        /// 查询中的事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="queryEventArgs"></param>
        private void InterfaceBusiness_OnQueryEvent(object sender, RE_QueryEventArgs queryEventArgs)
        {
            //XML格式的参数
            RE_BaseReqDTO RE_BaseReq = (RE_BaseReqDTO)queryEventArgs.CustomData;
            //json参数
            RE_ReqDTO data = new RE_ReqDTO();
            data.page = queryEventArgs.Page.PageIndex;
            //data.date_from = DateTime.Now.AddDays(-queryEventArgs.Page.Total).ToString("yyyy-MM-dd");
            //data.date_to = DateTime.Now.ToString("yyyy-MM-dd");
            RE_BaseReq.ParamsJson = GetJsonData(queryEventArgs.APINodes, queryEventArgs.ParentNode, data);
            //获取请求的XML字符串
            queryEventArgs.reqData = GetRequstXML(RE_BaseReq);
        }

        /// <summary>
        /// 查询执行后的事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="queryEventArgs"></param>
        private void InterfaceBusiness_AfterQueryEvent(object sender, RE_QueryEventArgs queryEventArgs)
        {

            try
            {
                //获取返回XML中的JSON结果
                var res = GetXMLResponse(queryEventArgs.ResultStr, (RE_BaseReqDTO)queryEventArgs.CustomData);
                //将查询后的数据转换成对应格式的数据
                RE_BaseResponseDTO<RE_ProductInventory> result = (RE_BaseResponseDTO<RE_ProductInventory>)JsonConvert.DeserializeObject<RE_BaseResponseDTO<RE_ProductInventory>>(res);
                if (result.ask == "Success")
                {
                    queryEventArgs.Success = true;
                    if (!result.nextPage)
                    {
                        //查询完成
                        queryEventArgs.Page.PageIndex = 1;
                        queryEventArgs.Page.Complete = true;
                        if (result.data.Count > 0) queryEventArgs.Rows = result.data;
                    }
                    else
                    {
                        //查询下一页
                        queryEventArgs.Page.PageIndex += 1;
                        queryEventArgs.Rows = result.data;
                    }
                }
                else
                { queryEventArgs.Success = false; }

            }
            catch (Exception ex)
            {
                queryEventArgs.Success = false;
                AddLog(SqlDb, ex.Message, InterfaceName, "erro", "");
            }

        }

        /// <summary>
        /// 执行增删改查业务
        /// </summary>
        //public async void ExecuteInterface()
        //{
        //    List<RE_ProductInventory> invList = await this.QueryAsync<RE_ProductInventory>(this.RE_Query, SqlDb);



        //}

        /// <summary>
        /// 执行增删改查业务
        /// </summary>
        public async void ExecuteInterface()
        {

            try
            {
                //获取源数据
                List<RE_ProductInventory> sourceData = await this.QueryAsync<RE_ProductInventory>(this.RE_Query, SqlDb);
                //拼接生成ID
                sourceData.ForEach(r => r.ID = r.warehouse_code + r.product_sku + r.product_barcode);
                //将重复的id编号变成唯一的id
                sourceData.GroupBy(x => x.ID).ForEach(x =>
                {
                    if (x.Count() > 1)
                    {
                        int c = 0;
                        x.ForEach(r =>
                        {
                            c++;
                            r.ID = r.ID + c;
                        });

                    }

                });


                if (sourceData.Count > 0)
                {
                    //获取产品列表
                    RE_ProductInterfaceBusiness RE_ProductInterface = new RE_ProductInterfaceBusiness();
                    List<RE_Product> prds = await RE_ProductInterface.QueryAsync<RE_Product>(this.RE_Query, SqlDb);

                    //批次库存信息同步数据库
                    List<RE_ProductInventory.Batch_Info> bachData = new List<RE_ProductInventory.Batch_Info>();
                    foreach (var item1 in sourceData)
                    {
                        var prd = prds.Where(x => x.product_sku == item1.product_sku);
                        if (!prd.IsNullOrEmpty()) item1.product_sku = prd.First().reference_no;
                        foreach (var item2 in item1.batch_info)
                        {
                            item2.product_sku = item1.product_sku;
                            item2.product_barcode = item1.product_barcode;
                            item2.warehouse_code = item1.warehouse_code;
                            item2.ID = item1.ID + item2.receiving_code + item2.stock_age;
                            bachData.Add(item2);
                        }
                    }
                    //同步数据库
                    SqlDBInterfaceBusiness sqlDBInterface = new SqlDBInterfaceBusiness(MapFields);
                    sqlDBInterface.ExecuteInterface<RE_ProductInventory>(sourceData, "SD_RE_ProductInventory");

                    //将ID相同的分组合并数量
                    List<RE_ProductInventory.Batch_Info> bachData_g = new List<RE_ProductInventory.Batch_Info>();
                    if (bachData.Count > 0)
                    {
                        foreach (var item1 in bachData.GroupBy(x => x.ID))
                        {
                            RE_ProductInventory.Batch_Info batch_Info = item1.First();
                            batch_Info.reserved_quantity = item1.Sum(x => x.reserved_quantity);
                            batch_Info.sellable_quantity = item1.Sum(x => x.sellable_quantity);
                            bachData_g.Add(batch_Info);
                        };
                        sqlDBInterface.Keys = GetMapField("RE_Query", "RE批次库存");
                        sqlDBInterface.ExecuteInterface<RE_ProductInventory.Batch_Info>(bachData_g, "SD_RE_InvBatchInfo");
                    }
                }
                else
                {
                    throw new NotImplementedException("目标/源查询无数据无法执行接口!!");

                }



            }
            catch (Exception ex)
            {
                AddLog(SqlDb, ex.Message, InterfaceName, "erro", "");
            }
        }



        /// <summary>
        /// 任务
        /// </summary>
        public void Job()
        {
            ExecuteInterface();
        }

        /// <summary>
        /// 获取请求的XML格式字符串
        /// </summary>
        public string GetRequstXML(RE_BaseReqDTO reqDTO)
        {
            string soapXml = "";
            if (!reqDTO.IsNullOrEmpty())
            {
                // 1. 创建XDocument
                XNamespace soapEnv = reqDTO.SoapEnv;
                XNamespace ns1 = reqDTO.Ns1;

                XDocument soapRequest = new XDocument(
                    new XDeclaration("1.0", "UTF-8", null),
                    new XElement(soapEnv + "Envelope",
                        new XAttribute(XNamespace.Xmlns + "SOAP-ENV", soapEnv),
                        new XAttribute(XNamespace.Xmlns + "ns1", ns1),
                        new XElement(soapEnv + "Body",
                            new XElement(ns1 + "callService",
                                new XElement("paramsJson", reqDTO.ParamsJson),
                                new XElement("appToken", reqDTO.AppToken),
                                new XElement("appKey", reqDTO.AppKey),
                                new XElement("service", reqDTO.Service)
                            )
                        )
                    )
                );
                // 2. 转换为字符串
                soapXml = soapRequest.ToString();
            }
            return soapXml;

        }


        /// <summary>
        /// 获取返回XML的json结果
        /// </summary>
        public string GetXMLResponse(string xmlString, RE_BaseReqDTO reqDTO)
        {
            string res = "";
            if (!reqDTO.IsNullOrEmpty() && xmlString.Contains("\"ask\":"))
            {
                XDocument xdoc = XDocument.Parse(xmlString);
                XNamespace soapEnv = reqDTO.SoapEnv;
                XNamespace ns1 = reqDTO.Ns1;

                // 获取response标签的内容
                res = xdoc
                    .Element(soapEnv + "Envelope")
                    .Element(soapEnv + "Body")
                    .Element(ns1 + "callServiceResponse")
                    .Element("response")?
                    .Value;
            }
            return res;

        }
    }

}
